/// @FUNCTION
/// @NAME ArrayFilter
/// @DESC Filters the content of the Table Array using the given criterias
/// @ACCESS Server
/// @MP False
/// @PARAM Array The array

/// @RETURN Array Filtered Values
/// @REQUIRE Nothing
/// @REMARK
/// @EXAMPLE [_array,[_col,_compare,_value],[_col,_compare,_value]] call CFUNC(ArrayFilter);

//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "arrays\fn_arrayFilter.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>
#ifndef __DUMP_INDENT__
#define __DUMP_INDENT__	"    "
#endif

private ["_array","_result","_filters","_filter_column","_filter_value","_filter_compare","_value","_match"];
TRACE_1("Start",_this);
TMFPROFILERSTART;
_result = [];
if (count _this <= 1) then {
	ERROR("Not enough parameters");
} else {
	_array = _this select 0;
	_filters = [];
	// No need to check if there are no lines
	if (count _array > 0) then {
		_max_column = 0;
		For [{_i = 1}, {_i < count _this}, {_i = _i + 1}] do {
			if (count (_this select _i) >= 3) then {
				// We add the filter to the array plus we set the filter operator right.
				_filter_compare = toUpper((_this select _i) select 1);
				if !(_filter_compare in ["==","!=",">","<",">=","<=","U==","U!=","IN","!IN"]) then {
					ERROR_1("Unknown comparison",_filter_compare);
					_filter_compare = "==";
				};
				(_this select _i) set [1,_filter_compare];
				_filter_column = (_this select _i) select 0;
				if (_filter_column > _max_column) then {_max_column = _filter_column};
				_filters set [ count _filters, (_this select _i)];
			};
		};
		// We loop through all lines
		{
			// We skip all lines which don't have enough columns
			_line = _x;
			if (typeName _line == typename []) then {
				if (count _line > _max_column) then {
					_match = false;
					try {
						{
							_filter_column = _x select 0;
							_filter_compare = _x select 1;
							_filter_value = _x select 2;
							_value = _line select _filter_column;
							_match = switch (_filter_compare) do {
								case "!=": { (_value != _filter_value) };
								case ">": { (_value > _filter_value) };
								case "<": { (_value < _filter_value) };
								case ">=": { (_value >= _filter_value) };
								case "<=": { (_value <= _filter_value) };
								case "IN": { (_value in _filter_value) };
								case "!IN": { !(_value in _filter_value) };
								case "U==": { (toUpper(_value) == toUpper(_filter_value)) };
								case "U!=": { (toUpper(_value) != toUpper(_filter_value)) };
								default { (_value == _filter_value) };
							};
							if (!_match) exitWith{};
						} foreach _filters;
					} catch {
						_match = false;
					};
					if (_match) then {_result set[count _result, _x];};
				};		
			};
		} foreach _array;
	};
};
TRACE_1("End",_result);
TMFPROFILERSTOP;
_result;
